package it.softphone.cmc.server.security;

import it.softphone.cmc.server.entity.AccountEntity;
import it.softphone.cmc.server.service.SystemManagerService;
import it.softphone.cmc.server.service.TenantService;
import it.softphone.cmc.server.service.exception.CMCException;
import it.softphone.cmc.shared.entity.Account;
import it.softphone.cmc.shared.entity.TenantUser;
import it.softphone.commons.spring.ApplicationConfig;

import java.util.Collections;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * 
 * @author bsorrentino
 *
 */
public class CMCDatastoreMultiTenantRealm extends AbstractMultiTenantRealm<AccountEntity> {

	final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(getClass().getName());
	
	public CMCDatastoreMultiTenantRealm() {
		super(new MemcacheManager());
	}

	@Override
	protected Logger getLogger() {
		return logger;
	}

	@Override
	protected AccountEntity findUser(String name, String tenant) {
		
		try {
			final SystemManagerService service = 
					ApplicationConfig.getBean(SystemManagerService.class);

			final Account account = service.findAccountById(name);

			if (account != null) {

				final TenantService tenantService = 
						ApplicationConfig.getBean(TenantService.class);

				final TenantService.Task<TenantUser> task = new TenantService.Task<TenantUser>() {

					@Override
					public TenantUser exec() throws Exception {

						return service.findUserByAccount(account);

					}
				};

				TenantUser user = null;
				
				if( tenant!= null ) {
					user = tenantService.execAsTenant(tenant, task);
				}
				
				if( user == null ) { 
					// INHERITS THE PERMISSION OF SYSTEM TENANT (IF PRESENT)
					user = tenantService.execAsSystemTenant(task);
				}

				if (user != null) {
					account.setUser(user);
				} else {
					logger.warning(String
							.format("The account [%s] has not a related user neither in System nor in [%s] tenants!",
									name, tenant));
				}
			}

			return (AccountEntity) account;

		} catch (CMCException e) {
			logger.log(Level.SEVERE,
					String.format("error retrieving account [%s]", name), e);
		}
		return null;
	}

	@Override
	protected String getUserPasswordHash(AccountEntity user) {
		return user.getPasswd();
	}

	@Override
	protected byte[] getUserSalt(AccountEntity user) {
		return user.getSalt();
	}

	@Override
	protected boolean isUserRegistered(AccountEntity user) {
		return user.isRegistered();
	}

	@Override
	protected boolean isUserSuspendend(AccountEntity user) {
		return user.isSuspended();
	}

	@Override
	protected Set<String> getUserPermissions(AccountEntity user) {
		final TenantUser tenantUser = user.getUser();
		
		if( tenantUser != null && tenantUser.isEnabled() ) {
			return tenantUser.getPermissions();
		}
		return Collections.emptySet();
	}

}
